﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DirectoryProvider
{
	public static class Tools
	{
		
		
		public static IEnumerable<KeyValuePair<string, object>> ToHash (this object hash)
		{

			Type tp = hash.GetType ();
			int pcount = 0;

			{
				var vinfo = tp.GetProperties ();

				foreach (var v in vinfo) {
					if (!string.IsNullOrEmpty (v.Name)) {
						var _value = v.GetValue (hash, null);
						yield return new KeyValuePair<string, object>(v.Name, _value);
					}
					pcount++;
				}
			}
			
			{
				var vinfo = tp.GetFields ();

				foreach (var v in vinfo) {
					if (!string.IsNullOrEmpty (v.Name)) {
						var _value = v.GetValue (hash);
						yield return new KeyValuePair<string, object>(v.Name, _value);
					}
					pcount++;
				}
			}
			
			yield break;
		}

		public static IEnumerable<KeyValuePair<string, string[]>> ToStringHash (this object hash)
		{
			
			
			foreach(var kvp in hash.ToHash()) {
				object val = kvp.Value;string key=kvp.Key;
									if (val != null) {

						var t = val.GetType ();
                        

						if (t.IsArray) {
							if (val is string[])
								yield return new KeyValuePair<string, string[]>(key, val as string[]);
							else {
								string[] values = (from x in val as object[] select (x ?? "").ToString ()).ToArray ();
								yield return new KeyValuePair<string, string[]>(key, values);
							}
                            
						} else {
							yield return new KeyValuePair<string,string[]>(key, new string[1] { Convert.ToString(val) });
						}

					} else
						yield return new KeyValuePair<string,string[]>(key, null);
			}
			
			/*
			
			Type tp = hash.GetType ();
			var vinfo = tp.GetProperties ();

			int pcount = 0;
			foreach (var v in vinfo) {
				if (!string.IsNullOrEmpty (v.Name)) {
					var _value = v.GetValue (hash, null);
					if (_value != null) {

						var t = _value.GetType ();
                        

						if (t.IsArray) {
							if (_value is string[])
								yield return new KeyValuePair<string, string[]>(v.Name, _value as string[]);
							else {
								string[] values = (from x in _value as object[] select (x ?? "").ToString ()).ToArray ();
								yield return new KeyValuePair<string, string[]>(v.Name, values);
							}
                            
						} else {
							yield return new KeyValuePair<string,string[]>(v.Name, new string[1] { Convert.ToString(_value) });
						}

					} else
						yield return new KeyValuePair<string,string[]>(v.Name, null);
				}
				pcount++;
			}

			yield break;
			*/
		}
		
/*		
		public static Dictionary<string, string[]> ToStringDictionary (this object hash)
		{
			
			Dictionary<string, string[]> dict = new Dictionary<string, string[]> ();
			
			
			Type tp = hash.GetType ();
			int pcount = 0;

			{
				var vinfo = tp.GetProperties ();

				foreach (var v in vinfo) {
					if (!string.IsNullOrEmpty (v.Name)) {
						var _value = v.GetValue (hash, null);
						if (_value != null) {

							var t = _value.GetType ();
                        

							if (t.IsArray) {
								if (_value is string[]) {
									dict.Add (v.Name, _value as string[]);
								} else {
									string[] values = (from x in _value as object[] select (x ?? "").ToString ()).ToArray ();
									dict.Add (v.Name, values);
								}
                            
							} else {
								dict.Add (v.Name, new string[1] { Convert.ToString (_value) });
							}

						} else
							dict.Add (v.Name, null);
					}
					pcount++;
				}
			}

			
			{
				var vinfo = tp.GetFields ();

				foreach (var v in vinfo) {
					if (!string.IsNullOrEmpty (v.Name)) {
						var _value = v.GetValue (hash);
						if (_value != null) {

							var t = _value.GetType ();
                        

							if (t.IsArray) {
								if (_value is string[]) {
									dict.Add (v.Name, _value as string[]);
								} else {
									string[] values = (from x in _value as object[] select (x ?? "").ToString ()).ToArray ();
									dict.Add (v.Name, values);
								}
                            
							} else {
								dict.Add (v.Name, new string[1] { Convert.ToString (_value) });
							}

						} else
							dict.Add (v.Name, null);
					}
					pcount++;
				}
			}

			
			return dict;
		}
*/
			
		public static bool IsNumeric (this string s)
		{
			if (string.IsNullOrEmpty (s)) {
				return false;
			}
			double d;
			return double.TryParse (s, out d);
		}
		
		public static double Numeric (this string s)
		{
			if (string.IsNullOrEmpty (s)) {
				return 0;
			}
			double d;
			return double.TryParse (s, out d) ? d : 0;
		}
		
		public static void Print (this System.Text.RegularExpressions.Match m, System.Text.RegularExpressions.Regex RegularExpression)
		{

			Console.WriteLine ("Depurando la Regex {0}", RegularExpression);

			if (m.Success) {

				Console.WriteLine (" - Resultados para {0}", m.Groups [0].Value);
				
				foreach (string gn in RegularExpression.GetGroupNames().Where(x=>!x.IsNumeric())) {
					Console.WriteLine ("  - {0}: {1}", gn, m.Groups [gn].Value);
				}
				
			} else {
				Console.WriteLine (" - No hay resultados para {0}", m.Groups [0].Value);
			}
			
			Console.WriteLine ();
		}
		
		public static System.DirectoryServices.PropertyValueCollection PropertyValues (this System.DirectoryServices.DirectoryEntry entry, string property)
		{
			return ((System.DirectoryServices.PropertyValueCollection)entry.Properties [property]);
		}
		
		public static IEnumerable<KeyValuePair<string,string>> Parse (this System.DirectoryServices.SearchResult sr)
		{
			
			if (sr != null) {
				
				foreach (string key in sr.Properties.PropertyNames) {
					var prop = sr.Properties [key];
					string[] values = new string[prop.Count];

					for (int i=0; i<prop.Count; i++)
						values [i] = prop [i] as string;
					
					yield return new KeyValuePair<string, string>(key, string.Join(";",values));
				}
				
			}
			
		}

		public static IEnumerable<KeyValuePair<string,string[]>> ParseValues (this System.DirectoryServices.SearchResult sr)
		{
			
			if (sr != null) {
				
				foreach (string key in sr.Properties.PropertyNames) {
					var prop = sr.Properties [key];
					string[] values = new string[prop.Count];

					for (int i=0; i<prop.Count; i++)
						values [i] = prop [i] as string;
					
					yield return new KeyValuePair<string, string[]>(key, values);
				}
				
			}
			
		}
	}
}
